package com.xy.blog.article.domain.service.impl;


import com.xy.blog.article.api.model.ArticleCategoryQuery;
import com.xy.blog.article.domain.constants.Leaf;
import com.xy.blog.article.domain.dao.impl.ArticleCategoryDaoImpl;
import com.xy.blog.article.domain.dao.model.ArticleCategoryDO;
import com.xy.blog.article.domain.exception.constants.ArticleCategoryErrorCode;
import com.xy.blog.article.domain.mapstruct.ArticleCategoryConverter;
import com.xy.blog.article.domain.service.IArticleCategoryService;
import com.xy.blog.article.domain.service.model.ArticleCategoryBO;
import com.xy.blog.core.exception.BaseException;
import com.xy.blog.core.id.SnowflakeIdWorker;
import com.xy.blog.core.springmvc.result.page.PageReq;
import com.xy.blog.core.springmvc.result.page.PageResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author zanhonglei
 * @version V1.0
 * @Description: 文章专栏
 * @date 2020/5/24
 */
@Service
public class ArticleCategoryServiceImpl implements IArticleCategoryService {


    @Autowired
    private ArticleCategoryDaoImpl articleCategoryDao;

    @Autowired
    private ArticleCategoryConverter articleCategoryConverter;

    @Override
    public PageResp<ArticleCategoryBO> listByPage(PageReq<ArticleCategoryQuery> req) throws BaseException {
        PageResp<ArticleCategoryBO> data = articleCategoryConverter.do2Bo(articleCategoryDao.listByPage(req));
        data.getList().forEach(item->{
            List<ArticleCategoryDO> articleCategoryDOS = articleCategoryDao.listByLevel(String.valueOf(item.getId()));
            item.setChildren(articleCategoryConverter.do2Bo(articleCategoryDOS));
        });
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(ArticleCategoryBO item) throws BaseException {
        ArticleCategoryDO articleCategoryDO = articleCategoryConverter.bo2Do(item);
        Long parentId = item.getParentId();
        Long id = SnowflakeIdWorker.generateId();

        ArticleCategoryDO query =  new ArticleCategoryDO();
        query.setName(item.getName());
        int i = articleCategoryDao.selectCount(query);
        if (i > 0) {
            throw new BaseException(ArticleCategoryErrorCode.NAME_ALREADY_EXISTS);
        }

        if (parentId != null) {
            ArticleCategoryDO parentDO = articleCategoryDao.getById(parentId);
            parentDO.setLeaf(Leaf.NOT_LEAF);
            parentDO.setUpdateTime(LocalDateTime.now());
            articleCategoryDao.updateById(parentDO);
            articleCategoryDO.setLevel(parentDO.getLevel() + "/" + id);
            articleCategoryDO.setParentId(parentDO.getId());
        } else {
            articleCategoryDO.setLevel(id + "");
            articleCategoryDO.setParentId(null);
        }
        articleCategoryDO.setLeaf(Leaf.IS_LEAF);
        articleCategoryDO.setId(id);
        articleCategoryDao.save(articleCategoryDO);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ArticleCategoryBO item) throws BaseException {
        ArticleCategoryDO articleCategoryDO = articleCategoryConverter.bo2Do(item);
        articleCategoryDao.updateById(articleCategoryDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteById(Long id) throws BaseException {
        ArticleCategoryDO articleCategoryDO = articleCategoryDao.getById(id);
        if (articleCategoryDO.getLeaf().equals(Leaf.NOT_LEAF)) {
            throw new BaseException(ArticleCategoryErrorCode.NOT_ALLOW_DELETE,articleCategoryDO.getName());
        }
        articleCategoryDao.deleteById(id);

    }

    @Override
    public ArticleCategoryBO getById(Long id) throws BaseException {
        return articleCategoryConverter.do2Bo(articleCategoryDao.getById(id));
    }

    @Override
    @Cacheable(cacheNames = "list-category")
    public Object list() {
        return articleCategoryConverter.do2Bo(articleCategoryDao.listAll());
    }



    @Override
    public Object listWithChildrenByLevel(Long level) {
//        List<ArticleCategoryDO> categoryDOS = articleCategoryDao.listAll();
//        List<Long> roots = new ArrayList<>();
//        List<ArticleCategoryDO> withOutRoot = new ArrayList<>();
//        Map<Long, ArticleCategoryDO> rootMap = new HashMap<>();
//        categoryDOS.forEach(item->{
//            if (item.getParentId() == null) {
//                roots.add(item.getId());
//                rootMap.put(item.getId(), item);
//            } else {
//                withOutRoot.add(item);
//            }
//        });
//
//        List<ArticleCategoryBO> data = new ArrayList<>(roots.size());
//
//        int i = 1;
//        for (Long id : roots) {
//            while (i++ < level) {
//                ArticleCategoryDO articleCategoryDO = rootMap.get(id);
//                for (ArticleCategoryDO item : withOutRoot) {
//                    String tempLevel = item.getLevel();
//                    if (tempLevel.split("/").length - 1 == i && tempLevel.contains(id.toString())) {
//
//                    }
//                }
//            }
//        }
//
//        if (level != null) {
//
//        } else {
//
//        }

        List<ArticleCategoryBO> articleCategoryBOS = articleCategoryConverter.do2Bo(articleCategoryDao.listParents());
        articleCategoryBOS.forEach(item->{
            List<ArticleCategoryDO> articleCategoryDOS = articleCategoryDao.listByLevel(String.valueOf(item.getId()));
            item.setChildren(articleCategoryConverter.do2Bo(articleCategoryDOS));
        });
        return articleCategoryBOS;
    }
}
